Dashboard.addWidget({ getId : function(){ return 'image-map-widget'; }, getName : function(){ return 'Image Map'; }, getDescription : function(){ return { en : 'Widget that display a set of KPIs or Goals over an image', de : 'Widget that display a set of KPIs or Goals over an image' }; }, getIconClass : function(){ return 'glyphicon glyphicon-picture'; }, createContent : function(configuration, currentWidgetInstanceId){ var _createCircleCode = function(color){ return''; } var _formatGoalStatusAsTrafficLightCode = function(status){ if(status == null) return _createCircleCode('lightgrey')+' '+_createCircleCode('lightgrey')+' '+_createCircleCode('lightgrey'); return _createCircleCode(status>0?'green ':'lightgrey')+' '+_createCircleCode(status==0?'grey ':'lightgrey')+' '+_createCircleCode(status<0?'red ':'lightgrey'); } var _formatKpiValue = function(value, measureUnit){ if(value == null) value = '--'; return '
' + value + ' ' + measureUnit + '
'; }; /*
').append( $('').on('load', function(){ $(this).parent().css('width',$(this).width()).css('height',$(this).height()); }) ).append(function(){ var res = []; for(var i=0;i0 && measure.columns.length>0 ? measure.data[0][measure.columns[0]] : null; }catch(e){ errorMsg = e; } objInfo = ModelManager.getKpiInfo(modelId, objectId); valueToDisplay = _formatKpiValue(lastValue, (measure!=null && measure.columns.length>0)?objInfo.getFieldInfos(measure.columns[0]).measureUnit:''); var valueDivDom = $('
' + objInfo.name + ':
' + valueToDisplay + '
').popover({ placement : 'auto right', container : 'body', html : true, title : objInfo.name + ' details', content : function(){ var html = '

'+objInfo.description+'

'; if(objInfo == null) return html; if(errorMsg != null){ html += '

Error Occurred: '+errorMsg+'

'; return html; } if(measure==null) throw 'Unexpected Exception!'; html += ''; html += ''; measure.columns.forEach(function(item){ html += ''; }); html += ''; measure.data.forEach(function(dataItem, index){ if(index > 10) return; html += ''; measure.columns.forEach(function(columnName){ html += ''; }); html += ''; }); if(measure.data.length > 10){ html += ''; measure.columns.forEach(function(item, i){ html += ''; }); html += ''; } if(measure.data.length == 0){ html += 'No information available'; } html += '
'+item+'
' + (dataItem[columnName]!=null?dataItem[columnName] + ' ' + objInfo.getFieldInfos(columnName).measureUnit :'') + '
'+(i==0?'...':'')+'
'; html += '

More informations:

'; html += ''; if(objInfo.type!=null) html += ''; for(var moreInfoKey in measure.moreInfo) html += ''; if(Object.keys(measure.moreInfo).length==0 && objInfo.type==null) html += ''; html += '
type'+objInfo.type+'
'+moreInfoKey+''+measure.moreInfo[moreInfoKey]+'
No additional infos available
'; return html; }(), trigger : 'hover' }); var divBorderColor = 'lightgrey'; var targetRangeStatusDom = null; if(measure!=null && measure.targetRangeAlgorithmResult!=null){ var targetRangeStatus = measure.targetRangeAlgorithmResult.status; divBorderColor = targetRangeStatus==null?'lightgrey':(targetRangeStatus>0?'green':(targetRangeStatus<0?'red':'grey')); var targetRangeStatusHtml = _createCircleCode(targetRangeStatus==null?'lightgrey':(targetRangeStatus>0?'green':(targetRangeStatus<0?'red':'grey'))); targetRangeStatusDom = $('
').append($(targetRangeStatusHtml)).popover({ placement : 'auto left', container : 'body', html : true, title : objInfo.name + ' target range status additional infos', content : function(){ var html = ''; for(var moreInfoKey in measure.targetRangeAlgorithmResult.moreInfo) html += ''; if(Object.keys(measure.targetRangeAlgorithmResult.moreInfo).length==0) html += ''; html += '
'+moreInfoKey+''+measure.targetRangeAlgorithmResult.moreInfo[moreInfoKey]+'
No additional infos available
'; return html; }(), trigger : 'hover' }); } var alertRangeStatusDomList = []; if(measure!=null) for(var j=0;j0 && divBorderColor!='red'?alertSuccessColor:divBorderColor; var alertCurrentStatusHtml = _createCircleCode(alertCurrentStatus==null?'lightgrey':(alertCurrentStatus==0?'grey':(alertCurrentStatus<0?'lightgrey':alertSuccessColor))); var alertCurrentStatusDom = $('
').append($(alertCurrentStatusHtml)).popover({ placement : 'auto left', container : 'body', html : true, title : objInfo.name + ' alert range status additional infos', content : function(){ var html = ''; for(var moreInfoKey in alertCurrentResult.moreInfo) html += ''; if(Object.keys(alertCurrentResult.moreInfo).length==0) html += ''; html += '
'+moreInfoKey+''+alertCurrentResult.moreInfo[moreInfoKey]+'
No additional infos available
'; return html; }(), trigger : 'hover' }); alertRangeStatusDomList.push(alertCurrentStatusDom); } var kpiDivDom = $('
').append( valueDivDom ).append( $('
').append( targetRangeStatusDom ).append( alertRangeStatusDomList ) ); res.push(kpiDivDom); } return res; }).append(function(){ var res = []; for(var i=0;i0?'green ':(lastValue<0?'red':'grey')); valueToDisplay = _formatGoalStatusAsTrafficLightCode(lastValue); var valueDivDom = $('
' + objInfo.name + ':
' + valueToDisplay + '
').popover({ placement : 'auto right', container : 'body', html : true, title : objInfo.name + ' details', content : function(){ var html = '

'+objInfo.description+'

'; if(objInfo == null) return html; if(errorMsg != null){ html += '

Error Occurred: '+errorMsg+'

'; return html; } if(measure==null) throw 'Unexpected Exception!'; html += ''; html += ''; html += ''; if(objInfo.type!=null) html += ''; for(var moreInfoKey in measure.moreInfo) html += ''; html += '
DetailsValues
status'+(measure.status==0?'UNKNOWN':(measure.status>0?'SUCCESS':'FAILURE'))+'
type'+objInfo.type+'
'+moreInfoKey+''+measure.moreInfo[moreInfoKey]+'
'; return html; }(), trigger : 'hover' }); var goalDivDom = $('
').append( valueDivDom ); res.push(goalDivDom); } return res; }); return ret; }, getConfiguration : function(){ return { image : { description : { en : '', de : '' }, value : 'custom', url : '', width : '' }, kpis : { description : { en : '', de : '' }, value : 'custom', kpiList : [{ modelId : '', id : '', pos_x : '', pos_y : '' }] }, goals : { description : { en : '', de : '' }, value : 'custom', goalList : [{ modelId : '', id : '', pos_x : '', pos_y : '' }] } }; }, createConfiguration : function(presetConfig){ var node = $('
').append( $('
').append( $('
').append( '

Click on the image to add KPIs/Goals

' ).append( $('
').append( $('').append( $('') ) ) ) ).append( $('
').append( $('
').append( $('').change(function(e){ _readImageHandler(e.target.files[0]); }) ).append( $('').click(function(){ _zoomImage(10); }) ).append( $('').click(function(){ _zoomImage(-10); }) ) ).append( $('
').append( $('').click(function(e){ var offset = $(this).offset(); var x = e.pageX - offset.left; var y = e.pageY - offset.top; _addMappedElement(null, null, null, x, y); }).on('load', function(){ node.find('#imageMapDiv').removeClass('dropZone'); }) ).on("drop", function(e) { e.preventDefault(); e.stopPropagation(); _readImageHandler(e.originalEvent.dataTransfer.files[0]); }).on("dragover", function(e) { e.preventDefault(); e.stopPropagation(); $(this).addClass('dragging'); }).on("dragleave", function(e) { e.preventDefault(); e.stopPropagation(); $(this).removeClass('dragging'); }) ) ) ); var _readImageHandler = function(file){ if(!file) return; if(!(window.File && window.FileReader && window.FileList && window.Blob)){ alert('The File APIs are not fully supported in this browser.'); return; } var reader = new FileReader(); reader.onload = function(e) { var content = e.target.result; node.find('#imageImg').attr('src', content); }; reader.readAsDataURL(file); }; var mappedElements = {}; var _zoomImage = function(percentage){ var imageNode = node.find('#imageImg'); var imageMapDivNode = node.find('#imageMapDiv'); var oldWidth = imageNode.width(); var oldHeight = imageNode.height(); var currentZoom = (imageNode.width()/imageMapDivNode.width())*100; currentZoom += percentage; if(currentZoom<=0) currentZoom = 0; var newWidthPx = currentZoom*imageMapDivNode.width()/100; imageNode.css('width', newWidthPx+'px'); var newWidth = imageNode.width(); var newHeight = imageNode.height(); for(var id in mappedElements){ var newX = newWidth/oldWidth*mappedElements[id].posX; var newY = newHeight/oldHeight*mappedElements[id].posY; _moveMappedElement(id, newX, newY); } }; var _addMappedElement = function(modelId, isGoal, objectId, posX, posY){ var uuid = 'imgMappedEl_'+Utils.generateUUID(); node.find('#imageMapDiv').append( $('
').hover(function(){ if(mappedElements[uuid].modelId != null && mappedElements[uuid].isGoal != null && mappedElements[uuid].objectId != null) node.find('#'+uuid+'_tr').toggleClass('success'); else node.find('#'+uuid+'_tr').toggleClass('danger'); node.find('#iamgeMapTableScrollDiv').animate({scrollTop:node.find('#'+uuid+'_tr').position().top}, 300); }) ); node.find('#iamgeMapTable').append( $('
').append( $('
').append( $('').append([ '' ]).change(function(){ var selectedVal = $(this).val(); var isGoal = null; var objectId = null; if(selectedVal!=''){ isGoal = selectedVal.startsWith('g_'); objectId = selectedVal.substr(2); } mappedElements[uuid].isGoal = isGoal; mappedElements[uuid].objectId = objectId; if(isGoal!=null && objectId!=null){ node.find('#'+uuid+'_div').css('background-color', 'GreenYellow'); node.find('#'+uuid+'_tr').addClass('success').removeClass('danger'); }else{ node.find('#'+uuid+'_div').css('background-color', 'red'); node.find('#'+uuid+'_tr').removeClass('success').addClass('danger'); } }) ).append( $('').click(function(){ delete mappedElements[uuid]; node.find('#'+uuid+'_div').remove(); node.find('#'+uuid+'_tr').remove(); }) ) ).hover(function(){ var scrollLeftVal = mappedElements[uuid].posX-(node.find('#imageMapDiv').width()/2); var scrollTopVal = mappedElements[uuid].posY-(node.find('#imageMapDiv').height()/2); node.find('#imageMapDiv').animate({scrollTop:scrollTopVal, scrollLeft:scrollLeftVal}, 300); node.find('#'+uuid+'_div').fadeTo(100, 0.1, function(){$(this).fadeTo(500, 1.0, function(){$(this).fadeTo(100, 0.1, function(){$(this).fadeTo(500, 1.0)})})}); }, function(){}) ); mappedElements[uuid] = { modelId : modelId, isGoal : isGoal, objectId : objectId, posX : posX, posY: posY }; if(modelId != null) node.find('#'+uuid+'_model_select').val(modelId).change(); if(modelId != null && isGoal != null && objectId != null) node.find('#'+uuid+'_kpi_goal_select').val((isGoal?'g_':'k_')+objectId).change(); }; var _moveMappedElement = function(id, newX, newY){ mappedElements[id].posX = newX; mappedElements[id].posY = newY; node.find('#'+id+'_div').css('top', newY+'px').css('left', newX+'px'); }; if(presetConfig != null){ node.find('#imageImg').attr('src', presetConfig.image.url); node.find('#imageImg').css('width', presetConfig.image.width+'px'); if(presetConfig.kpis.kpiList!=null) for(var i=0;i